import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

import { PageNotFoundComponent } from './core/components/page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './core/components/compose-message/compose-message.component';
import { CanDeactivateGuardService } from './core/guards/can-deactivate-guard.service';
import { AuthenticationGuardService } from './core/guards/authentication-guard.service';
import { SelectivePreloadingStrategy } from './core/shared/selective-preloading-strategy';

const routes: Routes = [
    // {
    //     path: 'users',
    //     loadChildren: 'src/app/users/users.module#UsersModule',
    //     canActivate: [AuthenticationGuardService],
    //     // canActivateChild: [AuthGuardService]     // canActivateChild here cannot protect the child router actually.
    // },
    {
        path: 'foo-demo',
        loadChildren: () => import('./foo-demo/foo-demo.module').then(m => m.FooDemoModule)
    },
    {
        // The path and component properties should be familiar. There's a new property, outlet, set to 'popup'. 
        // This route now targets the popup outlet and the ComposeMessageComponent will display there.
        path: 'compose',
        component: ComposeMessageComponent,
        outlet: 'popup'
    },
    {
        // Lazy loading has multiple benefits.

        // You can load feature areas only when requested by the user.
        // You can speed up load time for users that only visit certain areas of the application.
        // You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle

        // When the router navigates to this route, it uses the loadChildren string to dynamically load the AdminModule. 
        // Then it adds the AdminModule routes to its current route configuration. Finally, it loads the requested route 
        // to the destination admin component.

        // Take the final step and detach the admin feature set from the main application. The root AppModule must neither load nor reference the AdminModule or its files.

        // In app.module.ts, remove the AdminModule import statement from the top of the file and remove the AdminModule from the NgModule's imports array.
        path: 'admin',
        loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
        canLoad: [AuthenticationGuardService]     // It's guarding unauthorized loading of feature modules
    },
    {
        path: 'crisis-center',
        loadChildren: () => import('./crisis-center/crisis-center.module').then(m => m.CrisisCenterModule)
    },
    {
        path: 'heroes',
        loadChildren: () => import('./heroes/heroes.module').then(m => m.HeroesModule),
        canActivate: [AuthenticationGuardService]
    },
    {
        path: 'authentication',
        loadChildren: () => import('./authentication/authentication.module').then(m => m.AuthenticationModule)
        // data: { preload: true }
    },
    {
        path: 'accounts',
        loadChildren: () => import('./accounts/accounts.module').then(m => m.AccountsModule),
        // data: { preload: true },
        canActivate: [AuthenticationGuardService],
        // canActivateChild: [AuthGuardService]
    },
    {
        path: 'users-demo',
        loadChildren: () => import('./users-demo/users-demo.module').then(m => m.UsersDemoModule),
        canActivate: [AuthenticationGuardService],
        // canActivateChild: [AuthGuardService]     // canActivateChild here cannot protect the child router actually.
    },
    {
        path: 'roles',
        loadChildren: () => import('./roles/roles.module').then(m => m.RolesModule),
        canActivate: [AuthenticationGuardService]
    },
    {
        path: 'dynamic-form',
        loadChildren: () => import('./dynamic-form/dynamic-form.module').then(m => m.DynamicFormModule)
    },
    {
        // Technically, pathMatch = 'full' results in a route hit when the remaining, unmatched segments of the 
        // URL match ''. In this example, the redirect is in a top level route so the remaining URL and the 
        // entire URL are the same thing.

        // The other possible pathMatch value is 'prefix' which tells the router to match the redirect route when 
        // the remaining URL begins with the redirect route's prefix path.

        // Don't do that here. If the pathMatch value were 'prefix', every URL would match ''.

        // Try setting it to 'prefix' then click the Go to sidekicks button. Remember that's a bad URL and you 
        // should see the "Page not found" page. Instead, you're still on the "Heroes" page. Enter a bad URL in 
        // the browser address bar. You're instantly re-routed to /heroes. Every URL, good or bad, that falls 
        // through to this route definition will be a match.

        // The default route should redirect to the HeroListComponent only when the entire url is ''. Remember to 
        // restore the redirect to pathMatch = 'full'.
        path: '',
        redirectTo: 'accounts/dashboard',
        pathMatch: 'full'
    },
    {
        // A wildcard route has a path consisting of two asterisks. It matches every URL. The router will select 
        // this route if it can't match a route earlier in the configuration. A wildcard route can navigate to a 
        // custom "404 Not Found" component or redirect to an existing route.
        // The router selects the route with a first match wins strategy. Wildcard routes are the least specific 
        // routes in the route configuration. Be sure it is the last route in the configuration.
        path: '**',
        component: PageNotFoundComponent
    }
];

@NgModule({
    // Only call RouterModule.forRoot in the root AppRoutingModule (or the AppModule if that's where you 
    // register top level application routes). In any other module, you must call the RouterModule.forChild 
    // method to register additional routes.
    // Again, NEVER call RouterModule.forRoot in a feature-routing module.
    imports: [RouterModule.forRoot(
        routes,
        {
            enableTracing: false,                   // <-- debugging purposes only
            preloadingStrategy: PreloadAllModules   // Preloading: background loading of feature areas
            // preloadingStrategy: SelectivePreloadingStrategy
        }
    )],
    exports: [
        RouterModule
    ],
    providers: [
        CanDeactivateGuardService
    ]
})
export class AppRoutingModule { }